package com.hz.pay.center.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.domain.DataTag;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.hz.pay.center.config.PayCenterConfig;
import com.hz.pay.center.exception.BizException;
import com.hz.pay.center.model.MerchantInfo;
import com.hz.pay.center.model.PaySerialInfo;
import com.hz.pay.center.model.RefundSerialsInfo;
import com.hz.pay.center.resp.WechatRefundResp;
import com.hz.pay.center.service.IMchInfoService;
import com.hz.pay.center.service.IPaySerialService;
import com.hz.pay.center.service.IRefundSerialService;
import com.hz.pay.center.service.IRefundService;
import com.hz.pay.center.utils.AlipayUtils;
import com.hz.pay.center.utils.WechatUtil;
import com.pay.common.enums.PayChannelEnum;
import com.pay.common.req.RefundReq;
import com.pay.common.resp.RefundResultData;
import com.pay.common.utils.PayDigestUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;


/**
 * 退款业务接口实现
 */
@Service
public class RefundServiceImpl implements IRefundService {


    @Autowired
    private IMchInfoService mchInfoService;

    @Autowired
    private IPaySerialService paySerialService;

    @Autowired
    private IRefundSerialService refundSerialService;


    @Autowired
    private AlipayUtils alipayUtils;


    @Autowired
    private WechatUtil wechatUtil;


    @Autowired
    private PayCenterConfig payCenterConfig;

    private Logger logger = LoggerFactory.getLogger(RefundServiceImpl.class);


    @Override
    public RefundResultData doRefund(RefundReq refundReq) throws BizException {

        //最终目的 调用银行的退款接口 获取退款结果

        //1.1 请求验证

        //业务系统传来的签名
        String sign = refundReq.getSign();

        JSONObject object = (JSONObject)JSONObject.toJSON(refundReq);


        MerchantInfo merchantInfo = mchInfoService.queryByMchId(refundReq.getMchId());

        if (ObjectUtils.isEmpty(merchantInfo)){

            throw new BizException("商户id不存在");
        }

        if (!"0".equals(merchantInfo.getStatus())){

            throw new BizException("商户状态异常");
        }

        String newSign = null;

        try {
             newSign = PayDigestUtil.generateSignature(object,merchantInfo.getReqKey(),refundReq.getSignType());
        } catch (Exception e) {
            logger.error("Exception",e);
            throw new BizException(e.getMessage());
        }

        if(!refundReq.getSign().equals(newSign)){
            throw new BizException("验证签名失败");
        }


        //1.查询订单是否存在

        PaySerialInfo paySerialInfo = paySerialService.queryByPaySerialNo(refundReq.getOrderId());

        if (ObjectUtils.isEmpty(paySerialInfo)){

            //返回，订单号不存在或者状态不正确
            return null;
        }


        //2. 检查 是否超过最大退款天数 , 7天

       long maxMs = 604800000;

        long paySuccessTime = paySerialInfo.getPaySuccessTime().getTime(); //支付成功

        long now = new Date().getTime();

        if (now - paySuccessTime > maxMs){
            throw new BizException("超过最大退款天数");
        }


        //3. 单笔交易最多10次退款

        List<RefundSerialsInfo> refundSerialsInfoList = refundSerialService.queryByPaySerialNo(paySerialInfo.getPaySerialNo());
        if (refundSerialsInfoList.size() > payCenterConfig.getMaxRefundCount()){
            throw new BizException("超过退款次数");
        }

        //4. 金额是否超过可退金额。

        BigDecimal refundAmt = refundReq.getRefundAmt();

        if (paySerialInfo.getPayAmount().compareTo(refundAmt)< 0){
            throw new BizException("退款金额不能大于支付金额");
        }

        // 原来 支付100，
        //第一次退款 10  成功   t1
        //第二次退款 20  成功   t2


        //退款 80   t3

        // t1 + t2 + t3 <100


        BigDecimal totalRefundAmt = new BigDecimal("0");


        //数据已经退款的总金额
        for (RefundSerialsInfo refundSerialsInfo :refundSerialsInfoList){

            totalRefundAmt = totalRefundAmt.add(refundSerialsInfo.getRefundAmt());
        }

        // 当前申请退款的金额 + 数据库中已经退款的金额
        totalRefundAmt = totalRefundAmt.add(refundAmt);

        if (paySerialInfo.getPayAmount().compareTo(totalRefundAmt)< 0){
            throw new BizException("退款金额不能大于支付金额");
        }



        //6.插入退款流水，

        RefundSerialsInfo refundSerialsInfo = refundSerialService.createRefundSerial(refundReq);


        //根据支付渠道，调用支付公司的退款接口
        if (PayChannelEnum.ALIPAY.getCode().equals(refundReq.getPayChannel())){


            try {
                AlipayTradeRefundResponse alipayTradeRefundResponse = alipayUtils.alipayTradeRefund(paySerialInfo.getPaySerialNo(),
                        refundAmt,refundReq.getReason(),refundSerialsInfo.getRefundSerialNo());

                //解析对象
                String fundChange = alipayTradeRefundResponse.getFundChange();

//                alipayTradeRefundResponse.getCode()



                //更新退款状态
                RefundSerialsInfo record = new RefundSerialsInfo();

                if ("10000".equals(alipayTradeRefundResponse.getCode())) {

                    if (refundAmt.toString().equals(alipayTradeRefundResponse.getFundChange())){
                        record.setRefundStatus(""); //修改退款流水为成功
                    }


                } else{
                    //失败的

                    record.setRefundStatus("失败"); //修改退款流水为成功

                }

                //更新退款流水状态
                refundSerialService.updateRefundSerial(record);


                //封装接口对象返回

                RefundResultData refundResultData = new RefundResultData();

                refundResultData.setOrderId("");
                refundResultData.setRefundStatus("");

                //生成签名

                return refundResultData;


            } catch (AlipayApiException e) {
                logger.error("AlipayApiException",e);
               throw new BizException(e.getMessage());
            }

        } else if(PayChannelEnum.WECHAT.getCode().equals(refundReq.getPayChannel())){

            //调用微信的退款接口

            WechatRefundResp wechatRefundResp = wechatUtil.wechatTradeRefund(paySerialInfo.getPaySerialNo(),
                    refundAmt,refundSerialsInfo.getRefundSerialNo());
            RefundSerialsInfo record = new RefundSerialsInfo();

            if ("SUCCESS".equals(wechatRefundResp.getResult_code())){

                //更


                record.setRefundStatus("银行处理中");
                refundSerialService.updateRefundSerial(record);
            }else{

                record.setRefundStatus("失败");
                refundSerialService.updateRefundSerial(record);
            }


            //封装对象返回 RefundResultData， 生成签名

            return new RefundResultData();


        }
        return null;




    }
}
